/*
 * @描述: 
 * @创建者: kilomChou
 * @Date: 2021-05-03 23:03:54
 * @最后编辑: kilomChou
 * @LastEditTime: 2021-05-11 00:01:25
 */
import { _decorator, Component, Prefab, Node, NodePool, instantiate, Sprite, math, Label, UITransform, lerp } from 'cc';
import { Vec2 } from '../../common/core/vec2/Vec2';
import { ClientEvent, ED } from '../event/ClientEvent';
import { SnakeMod } from '../model/SnakeMod';
const { ccclass, property } = _decorator;

@ccclass('SnakeMgr')
export class SnakeMgr extends Component {

    @property(Prefab)
    snakeNamePrefab: Prefab
    @property(Prefab)
    snakeHeadPrefab: Prefab
    @property(Prefab)
    snakeNodePrefab: Prefab

    /** 蛇头节点对象池 */
    snakeHeadPool: NodePool = new NodePool();
    /** 蛇身节点对象池 */
    snakeNodePool: NodePool = new NodePool();
    /** id->snakeNode 蛇节点字典 */
    snakeDic: { [id: number]: Node } = {}

    onLoad() {

        ED.on(ClientEvent.SNAKE_LOAD, snakes => {
            //加载蛇
            snakes.forEach(snake => {
                let node = snake.node = new Node(snake.name);
                let nameNode = snake.nameNode = instantiate(this.snakeNamePrefab);
                this.node.addChild(node);
                node.addChild(nameNode);
                nameNode.getComponent(UITransform).priority = Number.MAX_SAFE_INTEGER;
                nameNode.getComponent(Label).string = snake.name;
                nameNode.active = false;
            })
        })

        ED.on(ClientEvent.SNAKE_UNLOAD, snakes => {
            //卸载蛇
            snakes.forEach(snake => {
                //卸载蛇节点
                snake.snakeNodeMap.forEach(snakeNode => {
                    if (snakeNode.idx == 0) {
                        this.snakeHeadPool.put(snakeNode.node);
                    } else {
                        this.snakeNodePool.put(snakeNode.node);
                    }
                })
                //从场景中销毁
                snake.node.destroy();
            })
        })

        ED.on(ClientEvent.SNAKE_NODE_LOAD, snakes => {

            snakes.forEach(snake => {
                let colorLen = snake.colors.length;
                snake.loadSnakeNodes.forEach(snakeNode => {
                    //加载蛇节点
                    let node: Node;
                    if (snakeNode.idx == 0) {
                        //头部
                        node = snake.headNode = snakeNode.node = this.snakeHeadPool.get() || instantiate(this.snakeHeadPrefab);
                    } else {
                        node = snakeNode.node = this.snakeNodePool.get() || instantiate(this.snakeNodePrefab);
                    }
                    snake.node.addChild(node);
                    node.setScale(snake.w, snake.w);
                    node.setPosition(snakeNode.x, snakeNode.y);
                    node.angle = snakeNode.ang - 90;
                    node.getComponent(Sprite).color = math.color(snake.colors[snakeNode.idx % colorLen]);
                    node.getComponent(UITransform).priority = Number.MAX_SAFE_INTEGER - 1 - snakeNode.idx;
                })
            })

        })

        ED.on(ClientEvent.SNAKE_NODE_UNLOAD, snakeNodes => {
            //卸载蛇节点
            snakeNodes.forEach(snakeNode => {
                if (snakeNode.idx == 0) {
                    this.snakeHeadPool.put(snakeNode.node);
                    snakeNode.snake.headNode = null;
                } else {
                    this.snakeNodePool.put(snakeNode.node);
                }
            })
        })
    }

    start() {


    }

    update(dt: number) {
        SnakeMod.snakeMap.forEach(snake => {
            let { nameNode, headNode, snakeNodeMap, w } = snake;
            snakeNodeMap && snakeNodeMap.forEach(snakeNode => {
                let { node } = snakeNode;
                if (node) {
                    let smooth = dt * 20;
                    node.setScale(w, w);
                    node.setPosition(lerp(node.position.x, snakeNode.x, smooth), lerp(node.position.y, snakeNode.y, smooth));
                    let diff = Vec2.angDiff(node.angle, snakeNode.ang)
                    node.angle = lerp(node.angle, node.angle + diff, smooth);
                }
            })
            if (nameNode) {
                if (headNode) {
                    nameNode.active = true;
                    let { x, y } = headNode.position;
                    nameNode.setPosition(x, y + w);
                    nameNode.setScale(w * 0.005, w * 0.005)
                } else {
                    nameNode.active = false;
                }
            }
        })
    }

}